home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 January: Mac OS SDK / Dev.CD Jan 96 SDK / Dev.CD Jan 96 SDK1.toast / Development Kits (Disc 1) / AOCE / Development Tools / Sample Code / Messaging Service Access Module / Internet PMSAM / Internet PMSAM source / spoolfromexternal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-08  |  9.6 KB  |  407 lines  |  [TEXT/MPS ]

  1. /*-------------------------------------------------------------------
  2.  
  3. AOCE Post Office Protocol (POP) / Simple Mail Transfer Protocol (SMTP)
  4. Mail Service Access Module
  5.  
  6. written by Steve Falkenburg-- MacDTS
  7. ©1991-1993 Apple Computer, Inc.
  8.  
  9. --------------
  10. change history
  11. --------------
  12.  
  13. SJF        02/19/93    update for beta build    b1
  14. SJF        10/29/92    update to a11            a11
  15. SJF        06/08/92    update to a8            a8
  16. SJF        02/15/92    first working version    a4.5
  17. SJF        10/16/91    initial coding            a3
  18.  
  19. ---------------------------------------------------------------------*/
  20.  
  21. #ifndef __TYPES__
  22. #include <Types.h>
  23. #endif
  24.  
  25. #ifndef __OCE__
  26. #include <OCE.h>
  27. #endif
  28.  
  29. #ifndef __OCEMAIL__
  30. #include <OCEMail.h>
  31. #endif
  32.  
  33. #include <string.h>
  34.  
  35. #include "const.h"
  36. #include "gwerrors.h"
  37. #include "mytypes.h"
  38. #include "globals.h"
  39. #include "utils.h"
  40. #include "parser.h"
  41. #include "pop.constants.h"
  42. #include "pop.protocol.h"
  43. #include "convertaddress.h"
  44. #include "spoolsystem.h"
  45. #include "spooltoaoce.h"
  46. #include "spoolfromexternal.h"
  47. #include "network.h"
  48.  
  49. // DoSlotPut
  50. //
  51. // called to get messages for this slot from the external network and put them into
  52. // the system via the toolbox
  53. //
  54. OSErr DoSlotPut(SlotSpec *slot)
  55. {
  56.     OSErr err;
  57.     unsigned long popServerAddress,popConnID;
  58.     short numMessages,numMsgIDs,messageIDIndex;
  59.     long mboxLength;
  60.     TMsgIDList messageIDs;        // allocated by routine called from here, de-allocated by us
  61.     TMsgID curMessageID;
  62.     Ptr headerData;                // allocated by routine called from here, de-allocated by us
  63.     FSSpec spoolSpec;
  64.     
  65.     TraceExecution("\pDoSlotPut");
  66.  
  67.     /* first, we need to grab the letters from POP and spool them */
  68.     
  69.     err = InitRemoteNetStuff();
  70.     if (err!=noErr)
  71.         return err;
  72.  
  73.     err = ConvertStringToAddr(slot->specInfo.popServer,&popServerAddress);
  74.     if (err!=noErr) {
  75.         return kInvalidPopServer;
  76.     }
  77.         
  78.     err = POP_InitiateConnection(popServerAddress,kPopPort,slot->dirIdentity.userName,slot->dirIdentity.password,&popConnID);
  79.     if (err!=noErr) {
  80.         return err;
  81.     }
  82.     
  83.     err = POP_GetDropStats(popConnID,&numMessages,&mboxLength);
  84.     if (err!=noErr) {
  85.         POP_CloseConnection(popConnID);
  86.         return err;
  87.     }
  88.     
  89.     err = POP_GetMessageIDs(popConnID,&messageIDs,&numMsgIDs);    // messageIDs allocated by call
  90.     if (err!=noErr) {
  91.         POP_CloseConnection(popConnID);
  92.         return err;
  93.     }
  94.  
  95.     for (messageIDIndex=0; messageIDIndex<numMsgIDs; messageIDIndex++) {
  96.  
  97.         err = CreateSpoolFile(&spoolSpec);    // make our spool file
  98.         if (err!=noErr)
  99.             return err;
  100.  
  101.         curMessageID = messageIDs[messageIDIndex];
  102.         err = POP_GetMessage(popConnID,curMessageID,&headerData,&spoolSpec);
  103.  
  104.         if (err==noErr) {
  105.  
  106.             err = SpoolFromPOP(&spoolSpec,headerData,slot);    // spool message into aoce form
  107.             if (err==noErr)
  108.                 err = SpoolIntoAOCE(&spoolSpec,slot);            // send spooled msg to aoce
  109.  
  110.             if (err!=noErr) {
  111.                 POP_CloseConnection(popConnID);
  112.                 return err;
  113.             }
  114.             DisposPtrChk(headerData);
  115.             if (MemError()!=noErr) {
  116.                 POP_CloseConnection(popConnID);
  117.                 return err;
  118.             }
  119.  
  120.             err = POP_DeleteMessage(popConnID,curMessageID);
  121.  
  122.         }
  123.         if (err!=noErr) {
  124.             POP_CloseConnection(popConnID);
  125.             return err;
  126.         }
  127.  
  128.         RemoveSpoolFile(&spoolSpec);
  129.  
  130.     }
  131.     
  132.     if (numMsgIDs!=0) {
  133.         DisposPtrChk(messageIDs);
  134.         if (MemError()!=noErr) {
  135.             POP_CloseConnection(popConnID);
  136.             return err;
  137.         }
  138.     }
  139.  
  140.     err = POP_CloseConnection(popConnID);
  141.     return err;
  142. }
  143.  
  144.  
  145. OSErr SpoolFromPOP(FSSpec *spoolSpec,Ptr header,SlotSpec *slot)
  146. {
  147.     long headerLength;
  148.     OSErr err;
  149.     char *headerData;
  150.     RString rStr;
  151.     
  152.     headerData = (char *)NewPtrChk(kMaxRecipSize);
  153.     if (MemError()!=noErr)
  154.         return MemError();
  155.         
  156.     headerLength = strlen(header);
  157.     
  158.     // spool from
  159.     
  160.     err = ExtractHeaderLine("From:",headerData,header);
  161.     if (err==noErr) {
  162.         err = SpoolAddresses(headerData,spoolSpec,kFromType,kAddrCreator,slot);
  163.         if (err!=noErr) {
  164.             DisposPtrChk((Ptr)headerData);
  165.             return err;
  166.         }
  167.     }
  168.     else {
  169.         // no from address, so put ourselves in the from...
  170.         strcpy(headerData,slot->dirIdentity.userName);
  171.         strcat(headerData,"@");
  172.         strcat(headerData,slot->specInfo.popServer);
  173.         err = SpoolAddresses(headerData,spoolSpec,kFromType,kAddrCreator,slot);
  174.         if (err!=noErr) {
  175.             DisposPtrChk((Ptr)headerData);
  176.             return err;
  177.         }
  178.     }
  179.     
  180.     // spool to
  181.     
  182.     err = ExtractHeaderLine("To:",headerData,header);
  183.     if (err==noErr) {
  184.         err = SpoolAddresses(headerData,spoolSpec,kToType,kAddrCreator,slot);
  185.         if (err!=noErr) {
  186.             DisposPtrChk((Ptr)headerData);
  187.             return err;
  188.         }
  189.     }
  190.     else {
  191.         // no to address, so put ourselves in as to so things will work (somewhat)
  192.         strcpy(headerData,slot->dirIdentity.userName);
  193.         strcat(headerData,"@");
  194.         strcat(headerData,slot->specInfo.popServer);
  195.         err = SpoolAddresses(headerData,spoolSpec,kToType,kAddrCreator,slot);
  196.         if (err!=noErr) {
  197.             DisposPtrChk((Ptr)headerData);
  198.             return err;
  199.         }
  200.     }
  201.             
  202.     // spool CC (optional)
  203.     
  204.     err = ExtractHeaderLine("Cc:",headerData,header);
  205.     if (err==noErr) {
  206.         err = SpoolAddresses(headerData,spoolSpec,kCCType,kAddrCreator,slot);
  207.         if (err!=noErr) {
  208.             DisposPtrChk((Ptr)headerData);
  209.             return err;
  210.         }
  211.     }
  212.     
  213.     // spool BCC (optional)
  214.     
  215.     err = ExtractHeaderLine("Bcc:",headerData,header);
  216.     if (err==noErr) {
  217.         err = SpoolAddresses(headerData,spoolSpec,kBCCType,kAddrCreator,slot);
  218.         if (err!=noErr) {
  219.             DisposPtrChk((Ptr)headerData);
  220.             return err;
  221.         }
  222.     }
  223.     
  224.     // spool subject
  225.     
  226.     err = ExtractHeaderLine("Subject:",headerData,header);
  227.     if (err==noErr) {
  228.         OCECToRString(headerData,smRoman,&rStr,kRStringMaxBytes);
  229.         err = SpoolToFile(spoolSpec,kSubjectType,kAttribCreator,0,(Ptr)&rStr,(unsigned long)rStr.dataLength+4);
  230.         if (err!=noErr) {
  231.             DisposPtrChk((Ptr)headerData);
  232.             return err;
  233.         }
  234.     }
  235.     
  236.     // spool message body
  237.     
  238.     err = SpoolMessageBody(spoolSpec);
  239.     if (err!=noErr) {
  240.         DisposPtrChk((Ptr)headerData);
  241.         return err;
  242.     }
  243.  
  244.     DisposPtrChk((Ptr)headerData);
  245.     return err;
  246. }
  247.  
  248.  
  249. OSErr ExtractHeaderLine(char *header,char *contents,char *text)
  250. {
  251.     char *lineEnd,*curLine,*tmpWord;
  252.     
  253.     lineEnd = text;
  254.     while (*lineEnd) {
  255.         GetLine(&curLine,&lineEnd);
  256.         if (strstr(curLine,header)==curLine) {
  257.             GetWord(&tmpWord,&curLine);
  258.             CopyAndUnfoldLine(contents,curLine);
  259.             return noErr;
  260.         }
  261.     }
  262.  
  263.     return kUnexpectedDataCondition;
  264. }
  265.  
  266.  
  267. OSErr SpoolAddresses(char *headerLine,FSSpec *spoolSpec,OSType spoolType,OSType spoolCreator,SlotSpec *slot)
  268. {
  269.     OSErr err;
  270.     short index;
  271.     char *tAddress,*startAddr,*endAddr,*realName;
  272.     char singleAddr[256];
  273.     short addrLen;
  274.     
  275.     // rli variables
  276.     
  277.     RLI rli;
  278.     PackedRLI pRLI;
  279.  
  280.     // rid types
  281.     
  282.     CreationID cid;
  283.     RString rName,rType;
  284.     LocalRecordID localRID;
  285.     RecordID RID;
  286.  
  287.     DSSpec theRecipient;
  288.     char pRecipient[kMaxRecipSize];
  289.     unsigned long pRecipLength;
  290.     RString xtnValueRStr;
  291.     
  292.     err = noErr;
  293.     index = 0;
  294.     
  295.     while (*headerLine && err==noErr) {
  296.         GetField(&tAddress,&headerLine,',',&addrLen);
  297.         strncpy(singleAddr,tAddress,addrLen);
  298.         singleAddr[addrLen] = '\0';
  299.         realName = startAddr = endAddr = nil;
  300.         
  301.         // search for "xxxxx <addr>" style address
  302.         
  303.         if (startAddr=strstr(singleAddr,"<")) {        // got one
  304.             *startAddr = '\0';
  305.             startAddr++;
  306.             endAddr = strstr(startAddr,">");
  307.             *endAddr = '\0';
  308.             realName = singleAddr;
  309.         }
  310.         
  311.         // if not, assume "addr (xxxxxxx)" style address
  312.         
  313.         else {
  314.             startAddr = singleAddr;
  315.             endAddr=strstr(singleAddr," ");
  316.             if (endAddr) {
  317.                 *endAddr = '\0';
  318.                 realName = strstr(singleAddr,"(");
  319.                 if (realName) {
  320.                     endAddr = strstr(realName,")");
  321.                     if (endAddr)
  322.                         *endAddr = '\0';
  323.                     else
  324.                         realName = nil;
  325.                 }
  326.             }
  327.         }
  328.         
  329.         if (!startAddr)                                // at this point, realName points to the user's real name
  330.             return kUnexpectedDataCondition;        // and startAddr points to their e-mail address
  331.  
  332.         if (!realName || *realName==0)
  333.             realName = startAddr;
  334.             
  335.         // make our RLI (and pack it)
  336.         
  337.         OCENewRLI(&rli,(DirectoryNamePtr)&slot->directoryName,&slot->discriminator,kNULLDNodeNumber,nil);
  338.         if (!OCEValidRLI(&rli))
  339.             return kUnexpectedAOCECondition;
  340.         err = OCEPackRLI(&rli,&pRLI,kRLIMaxBytes);
  341.         if (err!=noErr)
  342.             return err;
  343.         if (!OCEValidPackedRLI(&pRLI))
  344.             return kUnexpectedAOCECondition;
  345.             
  346.         // set up name, type rstrings and creation ID for local RID
  347.         
  348.         OCESetCreationIDtoNull(&cid);
  349.         OCECToRString(kUserRecTypeBody,smRoman,&rType,kRStringMaxBytes);
  350.         OCECToRString(realName,smRoman,&rName,kRStringMaxBytes);
  351.         
  352.         // make the local RID and the RID
  353.  
  354.         OCENewLocalRecordID (&rName,&rType,&cid,&localRID);                            
  355.         OCENewRecordID(&pRLI,&localRID,&RID);
  356.  
  357.         theRecipient.entitySpecifier = &RID;
  358.         theRecipient.extensionType = kPopAddrType;
  359.         OCECToRString(startAddr,smRoman,&xtnValueRStr,kRStringMaxChars);
  360.         theRecipient.extensionSize = xtnValueRStr.dataLength+4;
  361.         theRecipient.extensionValue = (Ptr)&xtnValueRStr;
  362.                 
  363.         pRecipLength = OCEPackedDSSpecSize(&theRecipient);
  364.         OCEPackDSSpec(&theRecipient,(PackedDSSpec *)&pRecipient,pRecipLength);
  365.         
  366.         err = SpoolToFile(spoolSpec,spoolType,spoolCreator,index++,(Ptr)&pRecipient,pRecipLength);
  367.     }
  368.     
  369.     return err;
  370. }
  371.  
  372.  
  373. /*    this call should read the raw unprocessed content out of the spool and write aoce formatted
  374.     content into the spool.  here's where we should insert clever code to extract picts, sound,
  375.     styled text, movies, and enclosures but for right now, we only support one huge text block */
  376.     
  377. OSErr SpoolMessageBody(FSSpec *spoolSpec)
  378. {
  379.     OSErr err;
  380.     Ptr bodyBuffer;
  381.     unsigned long dataLength,startOffset;
  382.     
  383.     bodyBuffer = NewPtrChk(kMaxBufferSize);
  384.     if (MemError()!=noErr)
  385.         return MemError();
  386.     
  387.     startOffset = 0;
  388.     do {
  389.         dataLength = kMaxBufferSize;
  390.         err = GetFromSpool(spoolSpec,kRawContentType,kRawContentCreator,0,bodyBuffer,
  391.                             &dataLength,startOffset);
  392.         if ((err==noErr)||(err==kMoreData)) {
  393.             if (startOffset==0)
  394.                 SpoolToFile(spoolSpec,kTextContent,kContentCreator,0,bodyBuffer,dataLength);
  395.             else
  396.                 AppendToSpool(spoolSpec,kTextContent,kContentCreator,0,bodyBuffer,dataLength);
  397.             startOffset += dataLength;
  398.         }
  399.     } while (err==kMoreData);
  400.     
  401.     if (err==kMoreData)
  402.         err = noErr;
  403.     
  404.     DisposPtrChk(bodyBuffer);
  405.     
  406.     return err;
  407. }